package com.matrix.kernel.util;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;

/**
 * 日期处理
 * 
 * @author chenshun
 * @email sunlightcs@gmail.com
 * @date 2016年12月21日 下午12:53:33
 */
public class DateUtils extends DateFormatUtils
{
	/** 时间格式(yyyy-MM-dd) */
	public final static String DATE_PATTERN = "yyyy-MM-dd";
	/** 时间格式(yyyy-MM-dd HH:mm:ss) */
	public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
	
	public static String format(Date date) {
        return format(date, DATE_PATTERN);
    }

    public static String format(Date date, String pattern) {
        if(date != null){
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    /**
     * Parses a string representing a date by trying a variety of different parsers.
     * The parse will try each parse pattern in turn.
     * A parse is only deemed successful if it parses the whole of the input string.
     * If no parse patterns match, a ParseException is thrown.
     * The parser will be lenient toward the parsed date.
     *
     * @param str           the date to parse, not null
     * @param parsePatterns the date format patterns to use, see SimpleDateFormat, not null
     * @return the parsed date
     * @throws IllegalArgumentException if the date string or pattern array is null
     * @throws ParseException           if none of the date patterns were suitable (or there were none)
     */
    public static Date parse(String str, String... parsePatterns) throws ParseException {
        return org.apache.commons.lang.time.DateUtils.parseDate(str, parsePatterns);
    }

    //yyyyMMdd
    private static Pattern pattern1 = Pattern.compile("^\\d{4}\\d{1,2}\\d{1,2}$");
    //yyyyMMdd HH:mm:dd
    private static Pattern pattern2 = Pattern.compile("^\\d{4}\\d{1,2}\\d{1,2} (0\\d{1}|1\\d{1}|2[0-3]):[0-5]\\d{1}:([0-5]\\d{1})$");
    //yyyy-MM-dd
    private static Pattern pattern3 = Pattern.compile("\\d{4}(\\-)\\d{1,2}\\1\\d{1,2}$");
    //yyyy-MM-dd HH:mm:dd
    private static Pattern pattern4 = Pattern.compile("\\d{4}(\\-)\\d{1,2}\\1\\d{1,2} (0\\d{1}|1\\d{1}|2[0-3]):[0-5]\\d{1}:([0-5]\\d{1})$");
    //yyyy.MM.dd
    private static Pattern pattern5 = Pattern.compile("\\d{4}(\\.)\\d{1,2}\\1\\d{1,2}$");
    //yyyy.MM.dd HH:mm:dd
    private static Pattern pattern6 = Pattern.compile("\\d{4}(\\.)\\d{1,2}\\1\\d{1,2} (0\\d{1}|1\\d{1}|2[0-3]):[0-5]\\d{1}:([0-5]\\d{1})$");
    //yyyy/MM/dd
    private static Pattern pattern7 = Pattern.compile("^\\d{4}(\\/)\\d{1,2}\\1\\d{1,2}$");
    //yyyy/MM/dd HH:mm:dd
    private static Pattern pattern8 = Pattern.compile("^\\d{4}(\\/)\\d{1,2}\\1\\d{1,2} (0\\d{1}|1\\d{1}|2[0-3]):[0-5]\\d{1}:([0-5]\\d{1})$");
    //yyyy年MM月dd日
    private static Pattern pattern9 = Pattern.compile("^\\d{4}(\\/)\\d{1,2}\\1\\d{1,2}$");
    //yyyy年MM月dd日 HH:mm:dd
    private static Pattern pattern10 = Pattern.compile("^\\d{4}(\\/)\\d{1,2}\\1\\d{1,2} (0\\d{1}|1\\d{1}|2[0-3]):[0-5]\\d{1}:([0-5]\\d{1})$");

    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
    private static Logger logger = LoggerFactory.getLogger(DateUtils.class);

    public static Date parse(String dateStr) {
        if (StringUtils.isEmpty(dateStr))
            return null;
        try {
            if (pattern1.matcher(dateStr).matches()) {
                return org.apache.commons.lang.time.DateUtils.parseDate(dateStr, new String[]{"yyyyMMdd"});
            }
            if (pattern2.matcher(dateStr).matches()) {
                return org.apache.commons.lang.time.DateUtils.parseDate(dateStr, new String[]{"yyyyMMdd HH:mm:ss"});
            }
            if (pattern3.matcher(dateStr).matches()) {
                return org.apache.commons.lang.time.DateUtils.parseDate(dateStr, new String[]{"yyyy-MM-dd"});
            }
            if (pattern4.matcher(dateStr).matches()) {
                return org.apache.commons.lang.time.DateUtils.parseDate(dateStr, new String[]{"yyyy-MM-dd HH:mm:ss"});
            }
            if (pattern5.matcher(dateStr).matches()) {
                return org.apache.commons.lang.time.DateUtils.parseDate(dateStr, new String[]{"yyyy.MM.dd"});
            }
            if (pattern6.matcher(dateStr).matches()) {
                return org.apache.commons.lang.time.DateUtils.parseDate(dateStr, new String[]{"yyyy.MM.dd HH:mm:ss"});
            }
            if (pattern7.matcher(dateStr).matches()) {
                return org.apache.commons.lang.time.DateUtils.parseDate(dateStr, new String[]{"yyyy/MM/dd"});
            }
            if (pattern8.matcher(dateStr).matches()) {
                return org.apache.commons.lang.time.DateUtils.parseDate(dateStr, new String[]{"yyyy/MM/dd HH:mm:ss"});
            }
            if (pattern9.matcher(dateStr).matches()) {
                return org.apache.commons.lang.time.DateUtils.parseDate(dateStr, new String[]{"yyyy年MM月dd日"});
            }
            if (pattern10.matcher(dateStr).matches()) {
                return org.apache.commons.lang.time.DateUtils.parseDate(dateStr, new String[]{"yyyy年MM月dd日 HH:mm:ss"});
            }
            return simpleDateFormat.parse(dateStr);
        } catch (ParseException ex) {
            logger.error(ex.getMessage(), ex);
        }
        return null;
    }

    public static Date parseStartDate(String dateStr) {
        if (StringUtils.isEmpty(dateStr))
            return null;

        if (pattern1.matcher(dateStr).matches() || pattern3.matcher(dateStr).matches() || pattern5.matcher(dateStr).matches() || pattern7.matcher(dateStr).matches() || pattern9.matcher(dateStr).matches())
            dateStr += " 00:00:00";

        return parse(dateStr);
    }

    public static Date parseEndDate(String dateStr) {
        if (StringUtils.isEmpty(dateStr))
            return null;

        if (pattern1.matcher(dateStr).matches() || pattern3.matcher(dateStr).matches() || pattern5.matcher(dateStr).matches() || pattern7.matcher(dateStr).matches() || pattern9.matcher(dateStr).matches())
            dateStr += " 23:59:59";

        return parse(dateStr);
    }
}
